home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume91
/
games
/
larn_123
/
part04
/
tgetent.c
< prev
Wrap
C/C++ Source or Header
|
1991-08-28
|
10KB
|
396 lines
/************************************************************************
* *
* Copyright (c) 1982, Fred Fish *
* All Rights Reserved *
* *
* This software and/or documentation is released for public *
* distribution for personal, non-commercial use only. *
* Limited rights to use, modify, and redistribute are hereby *
* granted for non-commercial purposes, provided that all *
* copyright notices remain intact and all changes are clearly *
* documented. The author makes no warranty of any kind with *
* respect to this product and explicitly disclaims any implied *
* warranties of merchantability or fitness for any particular *
* purpose. *
* *
************************************************************************
*/
/*
* LIBRARY FUNCTION
*
* tgetent load buffer with entry for specified terminal
*
* KEY WORDS
*
* termcap functions
* utility routines
*
* SYNOPSIS
*
* int tgetent(bp,name)
* char *bp;
* char *name;
*
* DESCRIPTION
*
* Extracts the entry for terminal <name> from the termcap file
* and places it in the character buffer <bp>. It is currently
* assumed that bp is at least 1024 characters. If the entry in
* the termcap file is larger than 1023 characters the excess
* characters will be discarded and appropriate status will
* be returned.
*
* Also note that since bp is used by other termcap
* routines, the storage associated with the termcap entry
* cannot be freed until all termcap calls are completed.
*
* Tgetent can be directed to look in a file other than
* the default (/etc/termcap) by defining an environment
* variable called TERMCAP to be the pathname of the desired
* termcap file. This is useful for debugging new entries.
#ifndef VMS
* NOTE: the pathname MUST begin with a '/' character.
*
* Also, if the string assigned to TERMCAP does not begin with
* a '/' and if the environment variable TERM matches <name> then
* the string assigned to TERMCAP is copied to buffer <bp>
* instead of reading a termcap file.
#endif
*
* If the termcap entry contains a "tc" string then the termcap
* entry named in the string is appended to the buffer (minus the
* names).
*
* RETURNS
*
* -1 if the termcap file cannot be opened
* 0 if no entry in termcap file matches <name>
* 1 if extraction is successful with no errors
* 2 if extraction is successful but entry truncated
*
* SEE ALSO
*
* tgetnum extract numeric type capability
* tgetflag test boolean type capability
* tgetstr get string value of capability
*
* AUTHOR
*
* Fred Fish
*
*/
#include <stdio.h>
#define TRUE 1
#define FALSE 0
#define BUFSIZE 1024 /* Assumed size of external buffer */
#define NO_FILE -1 /* Returned if can't open file */
#define NO_ENTRY 0 /* Returned if can't find entry */
#define SUCCESS 1 /* Returned if entry found ok */
#define TRUNCATED 2 /* Returned if entry found but trunc */
#ifdef MSDOS
FILE *fopenp();
#endif
#define DEFAULT_ROOT "termcap" /* name without path component */
#ifdef VMS
#define DEFAULT_FILE "sys$library:termcap"
#else
#define DEFAULT_FILE "/etc/termcap" /* default termcap filename */
#endif VMS
char *_tcpbuf; /* Place to remember buffer pointer */
/*
* PSEUDO CODE
*
* Begin tgetent
* Erase any previous buffer contents.
* Remember the buffer pointer.
* If termcap file is not found then
* If buffer was filled anyway then
* Return SUCCESS.
* Else
* Return NO_FILE.
* End if
* Else
* While records left to process
* If this is entry is what we want then
* Close the termcap file.
* If entry was truncated then
* Return TRUNCATED status
* Else
* Return SUCCESS status.
* End if
* End if
* End while
* Return NO_ENTRY status.
* End if
* End tgetent
*
*/
int tgetent(bp,name)
char *bp; /* Pointer to buffer (1024 char min) */
char *name; /* Pointer to terminal entry to find */
{
FILE *fp, *find_file();
char *nbp, tc[80];
*bp = (char)NULL;
_tcpbuf = bp;
if ((fp = find_file(bp)) == NULL) {
if (*bp != NULL) {
return(SUCCESS);
} else {
return(NO_FILE);
}
} else {
while (fgetlr(bp,BUFSIZE,fp)) {
if (gotcha(bp,name)) {
fclose(fp);
nbp = &bp[strlen(bp)-1];
if (*nbp != '\n') {
return(TRUNCATED);
} else {
/* check for a recursive call (i.e. :tc=vt100:)
* added 18-dec-86 RDE (single recursion...)
*/
char *area;
area = &tc[0];
if (tgetstr("tc", &area) == NULL)
return(SUCCESS);
else {
fp = find_file(0); /* know it works and is file */
while (fgetlr(nbp, BUFSIZE-(nbp-bp), fp)) {
if (gotcha(nbp,tc)) {
char *cp1, *cp2; /* scrunch out names */
fclose(fp);
cp1 = nbp;
while (*cp1++ != ':') /* search for first */
;
cp2 = nbp;
while (*cp2++ = *cp1++) /* move the chars. */
;
if (bp[strlen(bp)-1] != '\n') {
return(TRUNCATED);
} else {
return(SUCCESS);
}
}
}
return (NO_ENTRY);
}
}
}
}
return(NO_ENTRY);
}
}
/*
* INTERNAL FUNCTION
*
* find_file find the termcap file and open it if possible
*
* KEY WORDS
*
* internal functions
* find_file
*
* SYNOPSIS
*
* static FILE *find_file(bp)
* char *bp;
*
* DESCRIPTION
*
* Attempts to locate and open the termcap file. Also handles
* using the environment TERMCAP string as the actual buffer
* (that's why bp has to be an input parameter).
*
#ifdef VMS
* If TERMCAP is defined as a valid filespec then it will be
* opened. If this fails then the default termcap file will
* be used.
#else
* If TERMCAP is defined an begins with a '/' character then
* it is taken to be the pathname of the termcap file and
* an attempt is made to open it. If this fails then
* the default termcap file is used instead.
*
* If TERMCAP is defined but does not begin with a '/' then
* it is assumed to be the actual buffer contents provided
* that <name> matches the environment variable TERM.
#endif
*
* BUGS
*
* There is currently no way to be sure which termcap
* file was opened since the default will always be
* tried.
*
*/
/*
* PSEUDO CODE
*
* Begin find_file
* If there is a TERMCAP environment string then
* If the string is not null then
* If the string is a pathname then
* If that file is opened successfully then
* Return its pointer.
* End if
* Else
* If there is a TERM environment string then
* If TERM matches <name> then
* Copy TERMCAP string to buffer.
* Return NULL for no file.
* End if
* End if
* End if
* End if
* End if
* Open default termcap file and return results.
* End find_file
*
*/
static FILE *find_file(bp)
char *bp;
{
FILE *fp, *fopen();
char *cp, *ncp, *getenv();
if ((cp = getenv("TERMCAP")) != NULL) {
if (*cp != NULL) {
#ifdef VMS
if ((fp = fopen(cp, "r")) != NULL)
return(fp);
#else
if (*cp == '/' || *cp == '\\') {
if ((fp = fopen(cp,"r")) != NULL) {
return(fp);
}
} else {
if ((ncp = getenv("TERM")) != NULL) {
if (strcmp(cp,ncp) == 0) {
strcpy(bp,cp);
return((FILE *)NULL);
}
}
}
#endif
}
}
/*
* Try current directory, then /etc/termcap
*/
if (fp = fopen(DEFAULT_ROOT, "r"))
return fp;
else
#ifdef MSDOS
if (fp = fopen(DEFAULT_FILE, "r") )
return fp;
else /* try along the PATH */
return( fopenp(DEFAULT_ROOT, "r", NULL));
#else
return (fopen(DEFAULT_FILE, "r"));
#endif
}
/*
* INTERNAL FUNCTION
*
* gotcha test to see if entry is for specified terminal
*
* SYNOPSIS
*
* gotcha(bp,name)
* char *bp;
* char *name;
*
* DESCRIPTION
*
* Tests to see if the entry in buffer bp matches the terminal
* specified by name. Returns TRUE if match is detected, FALSE
* otherwise.
*
*/
/*
* PSEUDO CODE
*
* Begin gotcha
* If buffer character is comment character then
* Return FALSE since remainder is comment
* Else
* Initialize name scan pointer.
* Compare name and buffer until end or mismatch.
* If valid terminators for both name and buffer strings
* Return TRUE since a match was found.
* Else
* Find next non-name character in buffer.
* If not an alternate name separater character
* Return FALSE since no more names to check.
* Else
* Test next name and return results.
* End if
* End if
* End if
* End gotcha
*
*/
gotcha(bp,name)
char *bp;
char *name;
{
char *np;
if (*bp == '#') {
return(FALSE);
} else {
np = name;
while (*np == *bp && *np != NULL) {np++; bp++;}
if (*np == NULL && (*bp == NULL || *bp == '|' || *bp == ':')) {
return(TRUE);
} else {
while (*bp != NULL && *bp != ':' && *bp != '|') {bp++;}
if (*bp != '|') {
return(FALSE);
} else {
return(gotcha(++bp,name));
}
}
}
}
#ifdef MSDOS
/*
* index(buffer, char)
* Find character in buffer. Return the pointer
* to it. Shouldn't be necessary to write this
* myself but VMS didn't. Oh Well...
* Used by lots of files in the termcap library.
* Rich Ellison, 16-DEC-1986
*/
char
*index(buf, ch)
char *buf;
char ch;
{
register int c;
while ((c= *buf++) != '\0')
if (c == ch)
return (buf-1);
return (NULL);
}
#endif